#include <iostream>
#include <string.h>
#include <map>
using namespace std;

#define N 10

class MyString
{
public:
    MyString();
    MyString(const char *str);
    MyString(const MyString &str);
    ~MyString();

    MyString &operator=(const MyString &str);

    friend bool operator>(const MyString &t1, const MyString &t2);
    friend MyString operator+(const MyString &t1, const MyString &t2);
    friend ostream &operator<<(ostream &out, const MyString &t);

private:
    char *m_data;
    int m_length;
};

MyString::MyString()
{
    cout << "MyString::MyString()" << endl;
    m_data = NULL;
    m_length = 0;
}
MyString::MyString(const char *str)
{
    cout << "MyString::MyString(const char *str)" << endl;
    m_length = strlen(str);
    m_data = new char[m_length+1];
    strcpy(m_data, str);
}

MyString::MyString(const MyString &str)
{
    cout << "MyString::MyString(const MyString &str)" << endl;
    m_length = str.m_length;
    m_data = new char[m_length+1];
    strcpy(m_data, str.m_data);
}

MyString::~MyString()
{
    if(m_data) delete []m_data;
}

MyString &MyString::operator=(const MyString &str)
{
    cout << "MyString &MyString::operator=(const MyString &str)" << endl;
    if(this == &str) return *this;
    if(m_length < str.m_length)
    {
        delete []m_data;
        m_data = new char[str.m_length+1];
    }

    m_length = str.m_length;
    strcpy(m_data, str.m_data);
    return *this;
}

bool operator>(const MyString &t1, const MyString &t2)
{
    if(strcmp(t1.m_data, t2.m_data) > 0) return true;
    return false;
}

MyString operator+(const MyString &t1, const MyString &t2)
{
    MyString t;
    t.m_length = t1.m_length + t2.m_length;
    t.m_data = new char[t.m_length+1];
    strcpy(t.m_data, t1.m_data);
    strcat(t.m_data, t2.m_data);
    return t;
}

ostream &operator<<(ostream &out, const MyString &t)
{
    if(t.m_data != NULL) return out << t.m_data;
    return out << "-";
}

///**************************************************///

class Time
{
public:
    Time(){  }
    Time(int h, int m, int s);
    friend Time operator+(const Time &t1, const Time &t2);
    friend ostream &operator<<(ostream &out, const Time &t);
private:
    int m_hour;
    int m_minute;
    int m_second;
};

Time::Time(int h, int m, int s)
{
    m_hour = h;
    m_minute = m;
    m_second = s;
}
Time operator+(const Time &t1, const Time &t2)
{
    Time t;
    t.m_hour = t1.m_hour + t2.m_hour;
    t.m_minute = t1.m_minute + t2.m_minute;
    t.m_second = t1.m_second + t2.m_second;
    return t;
}
ostream &operator<<(ostream &out, const Time &t)
{
    return out << "[" << t.m_hour << ":" << t.m_minute
            << ":" << t.m_second << "]";
}

///**************************************************///

template <class T>
class Stack
{
public:
    Stack(){ m_top = 0; }
    ~Stack(){}

    bool isEmpty();
    bool isFull();

    void push(T e) { m_buff[m_top++] = e; }
    T pop() { return m_buff[--m_top]; }

private:
    T m_buff[N];
    int m_top;
};

template <class T>
bool Stack<T>::isEmpty()
{
    if(m_top == 0) return true;
    return false;
}

template <class T>
bool Stack<T>::isFull()
{
    if(m_top == N) return true;
    return false;
}

///**************************************************///

int main()
{
    map<MyString, Time> strMap;
    strMap["hello"] = Time(1,2,3);
    strMap["world"] = Time(4,5,6);
//    Stack<int> int_stack;
//    for(int i = 0; i < 20; i++)
//        if(int_stack.isFull() == false)
//           int_stack.push(i);a
//        else break;
//
//    while(int_stack.isEmpty() == false)
//        cout << int_stack.pop() << " ";
//    cout << endl;
//
//    Stack<MyString> str_stack;
//    str_stack.push("hello");
//    str_stack.push("world");
//    str_stack.push("hi");
//    str_stack.push("ai");
//    str_stack.push("123q");
//
//    while(str_stack.isEmpty() == false)
//        cout << str_stack.pop() << " ";
//    cout << endl;
//
//    Stack<Time> time_stack;
//    time_stack.push(Time(2,5,6));
//    time_stack.push(Time(3,5,6));
//    time_stack.push(Time(2,6,6));
//    time_stack.push(Time(99,5,6));
//    time_stack.push(Time(8,7,6));
//
//    while(time_stack.isEmpty() == false)
//        cout << time_stack.pop() << endl;
//    cout << endl;

    return 0;
}
